﻿#region References
using System;
using System.Configuration;
using System.IO;
using System.Security.Cryptography;
using System.Text;
using System.Web;

#endregion

namespace App_Code.Logic
{
    /// <summary>
    /// Summary description for EncryptionLogic
    /// </summary>
    public class EncryptionLogic
    {
        private static readonly byte[] _encryptionPassword = Encoding.ASCII.GetBytes(ConfigurationManager.AppSettings["encryptionKey"]);


        /// <summary>
        /// Encrypt a string.
        /// </summary>
        public static string Encrypt(string originalString, string initVector)
        {
            if (String.IsNullOrEmpty(originalString))
            {
                return String.Empty;
            }

            byte[] iv = GetInitialVector(initVector);

            DESCryptoServiceProvider cryptoProvider = new DESCryptoServiceProvider();

            cryptoProvider.Padding = PaddingMode.PKCS7;

            MemoryStream memoryStream = new MemoryStream();
            CryptoStream cryptoStream = new CryptoStream(memoryStream,
                                                         cryptoProvider.CreateEncryptor(_encryptionPassword, iv), CryptoStreamMode.Write);

            var bytes = Encoding.ASCII.GetBytes(originalString);

            cryptoStream.Write(bytes, 0, bytes.Length);
            cryptoStream.FlushFinalBlock();

            return Convert.ToBase64String(memoryStream.ToArray());
        }

        /// <summary>
        /// Decrypt string
        /// </summary>
        public static string Decrypt(string cryptedString, string initVector)
        {
            if (String.IsNullOrEmpty(cryptedString))
            {
                return String.Empty;
            }

            byte[] iv = GetInitialVector(initVector);

            byte[] cryptedBytes = Convert.FromBase64String(cryptedString);

            DESCryptoServiceProvider cryptoProvider = new DESCryptoServiceProvider();

            cryptoProvider.Padding = PaddingMode.PKCS7;

            MemoryStream memoryStream = new MemoryStream
                (cryptedBytes);
            CryptoStream cryptoStream = new CryptoStream(memoryStream,
                                                         cryptoProvider.CreateDecryptor(_encryptionPassword, iv), CryptoStreamMode.Read);
            StreamReader reader = new StreamReader(cryptoStream);
            return reader.ReadToEnd();
        }

        #region Private methods

        private static byte[] GetInitialVector(string desiredVector)
        {
            return (String.IsNullOrEmpty(desiredVector) || desiredVector.Length < 8)
                ? _encryptionPassword :
                Encoding.ASCII.GetBytes(desiredVector.ToLower().Substring(desiredVector.Length - 8, 8));
        }

        #endregion
    }
}